package de.nak.notendb.action;

import java.util.Map;

import com.opensymphony.xwork2.ActionSupport;

import de.nak.notendb.model.ExaminationResult;
import de.nak.notendb.model.OralExaminationResult;
import de.nak.notendb.service.exceptions.AccessToDatabaseNotPossibleException;
import de.nak.notendb.service.exceptions.NoExaminationResultAvailableException;
import de.nak.notendb.service.exceptions.NoOralExaminationPossibleException;
import de.nak.notendb.service.interfaces.IExaminationResultService;
import de.nak.notendb.service.interfaces.IOralExaminationResultService;
import de.nak.notendb.service.interfaces.ISupportService;

/**
 * Oral Exam Action class
 * 
 * @author Christian Baumhof
 * 
 */
public class OralExamAction extends ActionSupport {
	private static final long serialVersionUID = 5112036270988516947L;
	/**
	 * The examinationResultService interface
	 */
	private IExaminationResultService examinationResultService;
	/**
	 * The supportService interface.
	 */
	private ISupportService supportService;
	/**
	 * The oralExaminationService interface.
	 */
	private IOralExaminationResultService oralExaminationResultService;
	/**
	 * The id.
	 */
	private Long id;
	/**
	 * The examination result
	 */
	private ExaminationResult result;
	/**
	 * The boolean if exam is open
	 */
	private Boolean openExam;
	/**
	 * The oral examination result.
	 */
	private OralExaminationResult oralExaminationResult;
	/**
	 * The boolean if no oral exam is possible.
	 */
	private Boolean noOralExamPossible;
	/**
	 * The grades of the oral exam.
	 */
	private Map<Float, Float> grades;

	/**
	 * Execute Methode for loading objects
	 */
	@Override
	public String execute() throws Exception {
		// load result
		if (result == null) {
			result = examinationResultService.getExaminatioResult(id);
		}

		// load oral exam
		if (oralExaminationResult == null) {
			if (getValidOralExam() != null) {
				oralExaminationResult = getValidOralExam();
				openExam = false;
			} else {
				openExam = true;
			}
		} else {
			openExam = false;
		}

		// initialise noOralExamPossible
		if (noOralExamPossible == null) {
			noOralExamPossible = false;
		}

		// load valid grades
		grades = supportService.getValidGrades();

		return SUCCESS;
	}

	/**
	 * Method for adding an oral examination
	 * 
	 * @return status
	 */
	public String addOralExam() {
		try {
			result = oralExaminationResultService.addOralExaminationResult(id);
		} catch (NoOralExaminationPossibleException exception) {
			noOralExamPossible = true;
		} catch (NoExaminationResultAvailableException exception) {
			return "DATA_NOT_FOUND";
		}
		oralExaminationResult = getValidOralExam();
		return SUCCESS;
	}

	/**
	 * Method to save the oral examination result
	 * 
	 * @return status
	 */
	public String saveOralExam() {
		try {
			oralExaminationResultService.saveOralExaminationResult(oralExaminationResult, id);
		} catch (AccessToDatabaseNotPossibleException exception) {
			return ERROR;
		} catch (NoExaminationResultAvailableException exception) {
			return "DATA_NOT_FOUND";
		}
		return SUCCESS;
	}

	/**
	 * Returns the id.
	 * 
	 * @return id.
	 */
	public Long getId() {
		return id;
	}

	/**
	 * Setter for the id
	 * 
	 * @param id
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * Returns the id.
	 * 
	 * @return id.
	 */
	public ExaminationResult getResult() {
		return result;
	}

	/**
	 * Setter for the examination result service
	 * 
	 * @param examination result service
	 */
	public void setExaminationResultService(IExaminationResultService examinationResultService) {
		this.examinationResultService = examinationResultService;
	}

	/**
	 * Returns the id.
	 * 
	 * @return id.
	 */
	public OralExaminationResult getOralExaminationResult() {
		return oralExaminationResult;
	}

	/**
	 * Setter for the oral examination result
	 * 
	 * @param oral examination result
	 */
	public void setOralExaminationResult(OralExaminationResult oralExaminationResult) {
		this.oralExaminationResult = oralExaminationResult;
	}

	/**
	 * Returns the id.
	 * 
	 * @return id.
	 */
	public Boolean getOpenExam() {
		return openExam;
	}

	/**
	 * Setter for the oral examination result service
	 * 
	 * @param oral examination result service
	 */
	public void setOralExaminationResultService(IOralExaminationResultService oralExaminationResultService) {
		this.oralExaminationResultService = oralExaminationResultService;
	}

	/**
	 * Setter for the examination result
	 * 
	 * @param examination result
	 */
	public void setResult(ExaminationResult result) {
		this.result = result;
	}

	/**
	 * Returns the id.
	 * 
	 * @return id.
	 */
	public Boolean getNoOralExamPossible() {
		return noOralExamPossible;
	}

	/**
	 * Setter for the boolean if no oral exam is possible
	 * 
	 * @param boolean no oral exam possible
	 */
	public void setNoOralExamPossible(Boolean noOralExamPossible) {
		this.noOralExamPossible = noOralExamPossible;
	}

	/**
	 * Returns the id.
	 * 
	 * @return id.
	 */
	public Map<Float, Float> getGrades() {
		return grades;
	}

	/**
	 * Setter for the support service
	 * 
	 * @param selected subject id
	 */
	public void setSupportService(ISupportService supportService) {
		this.supportService = supportService;
	}

	/**
	 * Returns the id.
	 * 
	 * @return id.
	 */
	private OralExaminationResult getValidOralExam() {
		if (result.getOralExaminationResults() == null) {
			return null;
		}
		for (OralExaminationResult oralResult : result.getOralExaminationResults()) {
			if (oralResult.isValid()) {
				return oralResult;
			}
		}
		return null;
	}

}
